//
// RS Game Framework
// Copyright © 2009 Jedd Haberstro
// jhaberstro@gmail.com
// 
// $Id:
//

#ifndef RS_UNITTEST_TESTSUITEMANAGER_HPP
#define RS_UNITTEST_TESTSUITEMANAGER_HPP

#include "rs/unittest/TestSuite.hpp"
#include "rs/unittest/UnitTestForwards.hpp"
#include "rs/Portability.hpp"
#include <tr1/unordered_map>

namespace rs
{
    namespace unittest
    {
        // TODO: MAKE SINGLETON THREAD SAFE
        class TestSuiteManager
        {
        public:
            
            typedef std::tr1::unordered_map< Char const*, TestSuite* > TestSuiteContainer;
            typedef TestSuiteContainer::iterator Iterator;
            typedef TestSuiteContainer::const_iterator ConstIterator;
            
        public:
            
            static TestSuiteManager& Instance();
            
            void AddTestSuite(TestSuite* suite);

            TestSuite* GetTestSuite(Char const* suiteName);
            
            RsSize GetTestSuiteCount() const;
            
            Iterator Begin();

            ConstIterator Begin() const;
            
            Iterator End();
            
            ConstIterator End() const;
            
        private:
            
            TestSuiteManager();
            
            TestSuiteManager(TestSuiteManager const&);
            
            TestSuiteManager& operator=(TestSuiteManager const&);
            
        private:
            
            TestSuiteContainer suites_;
        };
        
        
        
        inline TestSuiteManager& TestSuiteManager::Instance() {
            static TestSuiteManager instance;
            return instance;
        }
        
        inline TestSuiteManager::TestSuiteManager() {
        }
        
        inline void TestSuiteManager::AddTestSuite(TestSuite* suite) {
            if (suites_.find(suite->GetName()) != suites_.end()) {
                suites_.insert(TestSuiteContainer::value_type(suite->GetName(), suite));
            }
        }

        inline TestSuite* TestSuiteManager::GetTestSuite(Char const* suiteName) {
            RS_ASSERT(suiteName != 0, "suiteName cannot be null");
            ConstIterator suite = suites_.find(suiteName);
            if (suite == suites_.end()) {
                TestSuite* newSuite = new TestSuite(suiteName);
                suites_.insert(TestSuiteContainer::value_type(suiteName, newSuite));
                return newSuite;
            }
            
            return suite->second;
            //return (suite->second == suites_.end()->second) ? 0 : *suite;
        }
        
        inline RsSize TestSuiteManager::GetTestSuiteCount() const {
            return suites_.size();
        }
        
        inline TestSuiteManager::Iterator TestSuiteManager::Begin() {
            return suites_.begin();
        }

        inline TestSuiteManager::ConstIterator TestSuiteManager::Begin() const {
            return suites_.begin();
        }
        
        inline TestSuiteManager::Iterator TestSuiteManager::End() {
            return suites_.end();
        }
        
        inline TestSuiteManager::ConstIterator TestSuiteManager::End() const {
            return suites_.end();
        }
    }
}


#endif // RS_UNITTEST_TESTSUITEMANAGER_HPP
